/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * 
 * Copyright 2010 yura, Version 2.0 (the "License");
 *
 * you may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * 
 * Unless required by applicable law or agreed to in writing, software
 *
 * distributed under the License is distributed on an "AS IS" BASIS,
 *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the License for the specific language governing permissions and
 *
 * limitations under the License.
 */

package org.opu.doc2db.document.datadocument;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.ElementList;

/**
 *  paragraph with list of enother paragraphs
 * 
 * @author yura
 */
public class ParagraphList<T extends Paragraph> extends Paragraph
        implements Iterable<T> {

    /** list of elements */
    @ElementList(inline=true, name="elements")
    protected List<T> elements;

    /** separator of data when callde method getText */
    protected String dataSeparator = "\t";

    /**
     *  Create list with all argument
     *
     * @param id id of paragraph
     * @param elements elements collections
     */
    public ParagraphList(@Attribute(name="id") String id,
            @ElementList(name="elements") Collection<T> elements) {
        
        super(id);

        this.elements = new ArrayList<T>();
        if (elements != null) {
            this.elementsAddAll(elements);
        }
    }

    /**
     *  Create list with 0 paragraph<br>
     *<pre>
     *    this(0, elements);
     *</pre>
     * @param elements
     */
    public ParagraphList(@ElementList(name="elements") Collection<T> elements) {
        this("", elements);
    }

    /**
     *  Create list withoute data, but with paragraph identificator
     *
     * @param id id of paragraph
     */
    public ParagraphList(@Attribute(name="id") String id) {
        this(id, null);
    }

    /**
     *  create empte list without arguments
     *<pre>
     *    this(null);
     *</pre>
     */
    public ParagraphList() {
        this("", null);
    }

    /**
     *  Returns the number of elements in elements list
     *
     * @return elements list size
     */
    public int elementsSize() {
        return elements.size();
    }

    /**
     *  Removes the element at the specified position in elements list.
     * Returns the element that was removed from the list.
     *
     * @param index the index of the element to be removed.
     * @returnthe element that was removed from the list.
     */
    public T elementsRemove(int index) {
        return elements.remove(index);
    }

    /**
     *  Removes the first occurrence of the specified element from elements list.
     *
     * @param o element to be removed from elements list, if present
     * @return  if elements list contained the specified element
     */
    public boolean elementsRemove(T o) {
        return elements.remove(o);
    }

    /**
     *  Returns true if elements list contains no elements.
     *
     * @return true if elements list contains no elements.
     */
    public boolean elementsIsEmpty() {
        return elements.isEmpty();
    }

    /**
     *  Returns the element at the specified position in elements list.
     *
     * @param index index of the element to return
     * @return the element at the specified position in elements list.
     */
    public T elementsGet(int index) {
        return elements.get(index);
    }

    /**
     *  Appends all of the elements in the specified collection
     * of element to the end of elements list
     *
     * @see element
     * @param c collection containing elements to be added to elements list
     * @return true if elements list changed as a result of the call
     */
    public boolean elementsAddAll(Collection<? extends T> c) {
        return elements.addAll(c);
    }

    /**
     *  Appends the element to the end of elements list
     *
     * @param e element to be appended to elements list
     * @return true if elements list changed as a result of the call
     */
    public boolean elementsAdd(T e) {
        return elements.add(e);
    }


    @Override
    public String getText() {
        StringBuilder sb = new StringBuilder();
        int size = elements.size();

        for (int i = 0; i < size; i++) {
            sb.append(elements.get(i).getText());

            if ( (i + 1) < size){
                sb.append(dataSeparator);
            }
        }

        return sb.toString();
    }

    @Override
    public Iterator<T> iterator() {
        return elements.iterator();
    }

    /**
     *  Return list contain all elements.
     * @return list contain all elements.
     */
    public List<T> getElements() {
        return new ArrayList<T>(elements);
    }

    /**
     *  Remove all old elements and added all new.
     * @param elements new list of elements.
     */
    public void setElements(List<T> elements) {
        this.elements = new ArrayList<T>();
        if (elements != null){
//            this.elements.addAll(elements);
            this.elementsAddAll(elements);
        }
    }
}
